package ru.jexp.rcp.supply.swtext.properties;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.databinding.observable.list.ListDiff;
import org.eclipse.core.databinding.observable.list.ListDiffVisitor;
import org.eclipse.core.databinding.property.INativePropertyListener;
import org.eclipse.core.databinding.property.ISimplePropertyListener;
import org.eclipse.jface.databinding.swt.WidgetListProperty;
import org.eclipse.swt.custom.CTabFolder;

import ru.jexp.rcp.supply.swtext.ICTabItemCreator;

public class CTabFolderItemsListProperty<TElementType> extends WidgetListProperty
{

	private ICTabItemCreator<?, TElementType> creator;
	private List<TElementType> items = new ArrayList<TElementType>();

	public CTabFolderItemsListProperty(ICTabItemCreator<?, TElementType> creator)
	{
		this.creator = creator;
	}

	@Override
	public Object getElementType()
	{
		return creator.getElementType();
	}

	public INativePropertyListener adaptListener(ISimplePropertyListener listener)
	{
		return null;
	}

	public String toString()
	{
		return "CTabFolder.items[] <String>"; //$NON-NLS-1$
	}

	@SuppressWarnings("rawtypes")
	protected void doSetList(Object source, List list, ListDiff diff)
	{
		doUpdateList(source, diff);
	}

	protected void doUpdateList(final Object source, ListDiff diff)
	{
		diff.accept(new ListDiffVisitor()
		{
			CTabFolder folder = (CTabFolder) source;

			@SuppressWarnings("unchecked")
			public void handleAdd(int index, Object element)
			{
				creator.createItem(folder, index, (TElementType) element);
				items.add(index, (TElementType) element);
			}

			public void handleRemove(int index, Object element)
			{
				folder.getItem(index).dispose();
				items.remove(index);
			}

			public void handleReplace(int index, Object oldElement, Object newElement)
			{
				handleRemove(index, oldElement);
				handleAdd(index, newElement);
			}
		});
	}

	@SuppressWarnings({ "rawtypes" })
	protected List doGetList(Object source)
	{
		return new ArrayList<TElementType>(items);
	}
}
